home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / util / callbacks.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-13  |  10KB  |  292 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. from __future__ import with_statement
  5. from introspect import funcinfo
  6. from primitives import Delegate
  7. from functools import wraps
  8. from logging import getLogger
  9. from traceback import print_exc
  10. import sys
  11. import threading
  12. log = getLogger('callbacks')
  13. CALLBACKS = ('success', 'error', 'timeout')
  14. call_later_lock = threading.Lock()
  15. call_laters = dict()
  16.  
  17. def register_call_later(threadname, call_later):
  18.     call_later_lock.__enter__()
  19.     
  20.     try:
  21.         call_laters[threadname] = call_later
  22.     finally:
  23.         pass
  24.  
  25.  
  26.  
  27. def unregister_call_later(threadname):
  28.     call_later_lock.__enter__()
  29.     
  30.     try:
  31.         call_laters.pop(threadname)
  32.     finally:
  33.         pass
  34.  
  35.  
  36.  
  37. DO_NOTHING = lambda *a, **k: pass
  38.  
  39. class CallLater(object):
  40.     
  41.     def __init__(self, cb, threadname = None):
  42.         if not threadname:
  43.             pass
  44.         self.threadname = threading.currentThread().getName()
  45.         if self.threadname not in call_laters:
  46.             
  47.             try:
  48.                 cb_dbg_str = ', '.join((lambda .0: for s in .0:
  49. str(s))([
  50.                     funcinfo(cb),
  51.                     cb.func_code.co_filename,
  52.                     cb.func_code.co_firstlineno]))
  53.             except Exception:
  54.                 cb_dbg_str = 'Error making debug string. Repr is: {%s}' % funcinfo(cb)
  55.  
  56.             if cb is not DO_NOTHING:
  57.                 pass
  58.             
  59.         
  60.         self.cb = cb
  61.  
  62.     
  63.     def __repr__(self):
  64.         return '<%s %s>' % (type(self).__name__, funcinfo(self.cb))
  65.  
  66.     
  67.     def __call__(self, *a, **k):
  68.         if threading.currentThread().getName() != self.threadname and self.threadname in call_laters:
  69.             
  70.             try:
  71.                 return (None, None, call_laters[self.threadname])((lambda : self.cb(*a, **k)))
  72.             except Exception:
  73.                 print >>sys.stderr, 'callback is %s' % funcinfo(self.cb)
  74.                 raise 
  75.             except:
  76.                 None<EXCEPTION MATCH>Exception
  77.             
  78.  
  79.         None<EXCEPTION MATCH>Exception
  80.         
  81.         try:
  82.             return self.cb(*a, **k)
  83.         except Exception:
  84.             import sys as sys
  85.             print >>sys.stderr, '%s in %s (%s). args/kwargs are: %r,%r' % (getattr(self.cb, '__name__', funcinfo(self.cb)), self.cb.__module__, funcinfo(self.cb), a, k)
  86.             raise 
  87.  
  88.  
  89.  
  90.  
  91. class CallLaterDelegate(Delegate):
  92.     
  93.     def __init__(self, *a):
  94.         Delegate.__init__(self, (lambda .0: for x in .0:
  95. CallLater(x))(a))
  96.  
  97.     
  98.     def __iadd__(self, f):
  99.         if isinstance(f, list):
  100.             for thing in f:
  101.                 self += thing
  102.             
  103.         else:
  104.             self.append(CallLater(f))
  105.         return self
  106.  
  107.  
  108.  
  109. class Callback(object):
  110.     normal_callback_names = CALLBACKS
  111.     
  112.     def __init__(self, **cbs):
  113.         for name, callback in cbs.iteritems():
  114.             if not callable(callback):
  115.                 raise TypeError('keyword args to Callback must be callable: %s' % name)
  116.             
  117.             setattr(self, name, CallLaterDelegate(callback))
  118.             attr = getattr(self, name)
  119.         
  120.  
  121.     
  122.     def __getattr__(self, attr):
  123.         
  124.         try:
  125.             return object.__getattribute__(self, attr)
  126.         except AttributeError:
  127.             if attr in self.normal_callback_names:
  128.                 return CallLaterDelegate()
  129.             else:
  130.                 raise 
  131.         except:
  132.             attr in self.normal_callback_names
  133.  
  134.  
  135.     
  136.     def __setattr__(self, attr, val):
  137.         object.__setattr__(self, attr, val)
  138.  
  139.     
  140.     def __call__(self, *a, **k):
  141.         return self.success(*a, **k)
  142.  
  143.     
  144.     def __repr__(self):
  145.         return '<%s %s>' % (type(self).__name__, ' '.join((lambda .0: for item in .0:
  146. '%s=%s' % item)(self.__dict__.items())))
  147.  
  148.  
  149. EMPTY_CALLBACK = Callback()
  150. DefaultCallback = EMPTY_CALLBACK
  151. CALLBACK_ATTR = '_iscallback'
  152.  
  153. def callsback(func):
  154.     
  155.     def wrapper(*secret_a, **secret_kws):
  156.         cb = None
  157.         if 'callback' in secret_kws:
  158.             if (any,)((lambda .0: for cbname in .0:
  159. cbname in secret_kws)(CALLBACKS)):
  160.                 raise AssertionError('use callback or individual callbacks')
  161.             
  162.             cb = secret_kws['callback']
  163.         else:
  164.             for cbname in CALLBACKS:
  165.                 if cbname in secret_kws:
  166.                     if cb is None:
  167.                         cb = Callback()
  168.                     
  169.                     if not callable(secret_kws[cbname]):
  170.                         raise TypeError('%s must be callable' % cbname)
  171.                     
  172.                     mycb = CallLaterDelegate(secret_kws[cbname])
  173.                     setattr(cb, cbname, mycb)
  174.                     del secret_kws[cbname]
  175.                     continue
  176.             
  177.             secret_kws['callback'] = cb
  178.         if cb is None:
  179.             secret_kws['callback'] = cb = Callback()
  180.         
  181.         
  182.         try:
  183.             val = func(*secret_a, **secret_kws)
  184.         except Exception:
  185.             e = None
  186.             print_exc()
  187.             callany = callany
  188.             import util
  189.             if not callany(cb.error, e):
  190.                 raise 
  191.             
  192.             val = None
  193.  
  194.         if val is True:
  195.             cb.success()
  196.         
  197.         return val
  198.  
  199.     wrapper = (wraps(func),)(wrapper)
  200.     setattr(wrapper, CALLBACK_ATTR, True)
  201.     return wrapper
  202.  
  203.  
  204. def is_callsback(f):
  205.     return bool(getattr(f, CALLBACK_ATTR, False))
  206.  
  207.  
  208. def do_cb(seq, callback = None):
  209.     CallbackSequence(seq, callback = callback)()
  210.  
  211. do_cb = callsback(do_cb)
  212.  
  213. class CallbackSequence(object):
  214.     
  215.     def __init__(self, sequence, callback):
  216.         self.iter = iter(sequence)
  217.         self.callback = callback
  218.         self.n = 0
  219.  
  220.     
  221.     def __call__(self, *a):
  222.         self.n = self.n + 1
  223.         
  224.         try:
  225.             next = self.iter.next()
  226.         except StopIteration:
  227.             log.debug('stop iteration, calling success: %r', funcinfo(self.callback.success))
  228.             self.callback.success()
  229.  
  230.         log.debug('%s #%d: %r', funcinfo(self.callback), self.n, funcinfo(next))
  231.         next(*a, **dict(success = self, error = self.callback.error))
  232.  
  233.  
  234.  
  235. def do_cb_na(seq, callback = None):
  236.     CallbackSequenceNoArgs(seq, callback = callback)()
  237.  
  238. do_cb_na = callsback(do_cb_na)
  239.  
  240. class CallbackSequenceNoArgs(object):
  241.     
  242.     def __init__(self, sequence, callback):
  243.         self.iter = iter(sequence)
  244.         self.callback = callback
  245.         self.n = 0
  246.  
  247.     
  248.     def __call__(self, *a):
  249.         self.n = self.n + 1
  250.         
  251.         try:
  252.             next = self.iter.next()
  253.         except StopIteration:
  254.             log.debug('stop iteration, calling success: %r', funcinfo(self.callback.success))
  255.             self.callback.success()
  256.  
  257.         log.debug('%s #%d: %r', funcinfo(self.callback), self.n, funcinfo(next))
  258.         next(**dict(success = self, error = self.callback.error))
  259.  
  260.  
  261.  
  262. def wxcall(func):
  263.     
  264.     def wrapper(*a, **k):
  265.         CallLater(func, threadname = 'MainThread')(*a, **k)
  266.  
  267.     wrapper = (wraps(func),)(wrapper)
  268.     return wrapper
  269.  
  270. if __name__ == '__main__':
  271.     
  272.     class MyProtocol(object):
  273.         
  274.         def networkOperation(self, someArg, callback = None):
  275.             callback.success()
  276.  
  277.         networkOperation = callsback(networkOperation)
  278.  
  279.     
  280.     def good():
  281.         print 'success'
  282.  
  283.     
  284.     def bad():
  285.         print 'bad'
  286.  
  287.     c = Callback(success = good)
  288.     MyProtocol().networkOperation(5, callback = c)
  289.     MyProtocol().networkOperation(5, success = good)
  290.     MyProtocol().networkOperation(5)
  291.  
  292.